'''
Additions to PyQt4 modules.
'''

import cgi
import re

def append_html(text_edit, new_html):
    """
    Appends the given HTML to the bottom of text_edit's contents.
    """

    # TODO: Better HTML processing needed?
    # E.g., use BeautifulSoup to handle any trailing <body> tag?
    
    if text_edit.toPlainText() == "":
        text_edit.setHtml("<body>%s</body>" % new_html)
        return
    
    html = text_edit.toHtml()
    m = re.match(r'(.*)(</body>\s*(?:</html>)?\s*)$', html)
    if m:
        html = m.group(1)
        after = m.group(2)
    else:
        after = ""
    text_edit.setHtml(html + new_html + after)

def find_data(combo, f):
    """
    Calls f for the data associated with each item in combo.  Returns the index
    of the first item for which f returns true.
    """
    for i in range(combo.count()):
        if f(combo.itemData(i).toPyObject()):
            return i
    else:
        return -1

class Fluent(object):
    """
    Presents a fluent interface to the passed-in parameter.
    
    Not Qt-specific, but that's where it will most likely be used.
    
    For example, you can take the following code:
    msg = QMessageBox()
    msg.setText("An error has occurred!")
    msg.setItem(QMessageBox.Critical)
    msg.exec_()
    
    and replace it with this:
    Fluent(QMessageBox()).setText("An error has occurred!").setIcon(QMessageBox.Critical)._exec()
    """
    # TODO: Ought to just use PyQt's properties support: http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#support-for-qt-properties
    def __init__(self, obj):
        self.obj = obj
        
    def __getattr__(self, name):
        def l(*args, **kwargs):
            result = getattr(self.obj, name)(*args, **kwargs)
            if result is not None:
                return result
            else:
                return self
        return l

class TextEditAppender(object):
    """
    Offers a file object-style interface to a QTextEdit's or QTextBrowser's
    contents.
    """
    def __init__(self, text_area):
        self.text_area = text_area
        
    def write(self, s):
        s = cgi.escape(s)
        s = s.replace("\n", "<br/>")
        s = unicode(s, "utf_8")
        
        append_html(self.text_area, s)